/*
 * Created on 2006-2-5
 *
 */
package org.faquir.license;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;

import org.apache.commons.lang.time.DateUtils;
import org.faquir.license.util.FileEncoder;

public class PropertiesLicense implements License
{
    private LicenseData getLicenseData(InputStream is) throws Exception
    {
        Properties p = new Properties();
        p.load(is);
        LicenseData data = new LicenseData();
        data.setType(p.getProperty("type"));
        data.setStatus(p.getProperty("status"));
        if ("closed".equals(data.getStatus()))
        {
            return data;
        }
        if ("date".equals(data.getType()))
        {
            data.setFrom(DateUtils.parseDate(p.getProperty("from"),
                    new String[]
                    { "yyyy-MM-dd", "yyyy/MM/dd" }));
            data.setTo(DateUtils.parseDate(p.getProperty("to"), new String[]
            { "yyyy-MM-dd", "yyyy/MM/dd" }));
        }
        else if ("times".equals(data.getType()))
        {
            data.setCurrentTimes(Integer.parseInt(p.getProperty("current")));
            data.setTotalTimes(Integer.parseInt(p.getProperty("total")));
        }
        return data;
    }

    private void setLicenseData(LicenseData data, String licenseFilePath)
            throws Exception
    {
        Properties p = new Properties();
        p.setProperty("type", data.getType());
        p.setProperty("status", data.getStatus());
        if ("date".equals(data.getType()))
        {
            SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd");
            
            p.setProperty("from", formater.format(data.getFrom()));
            p.setProperty("to", formater.format(data.getTo()));
        }
        if ("times".equals(data.getType()))
        {
            p.setProperty("total", Integer.toString(data.getTotalTimes()));
            p.setProperty("current", Integer.toString(data.getCurrentTimes()));
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        p.store(baos, "the license of analyst,modify in" + new Date());
        FileEncoder.encryptFile(baos.toByteArray(), licenseFilePath);
    }

    private boolean judgeRes(InputStream is, String licensePath)
    {
        try
        {
            LicenseData licenseData = getLicenseData(is);

            if ("closed".equals(licenseData.getStatus()))
            {
                return false;
            }
            if ("nolimited".equals(licenseData.getType()))
            {
                return true;
            }
            else if ("date".equals(licenseData.getType()))
            {
                Date now = new Date();
                if (now.after(licenseData.getFrom())
                        && now.before(licenseData.getTo()))
                {
                    return true;
                }
                else
                {
                    licenseData.setType("closed");
                    setLicenseData(licenseData, licensePath);
                    return false;
                }
            }
            else if ("times".equals(licenseData.getType()))
            {
                if (licenseData.getCurrentTimes() >= licenseData
                        .getTotalTimes())
                {
                    licenseData.setType("closed");
                    setLicenseData(licenseData, licensePath);
                    return false;
                }
                else
                {
                    licenseData
                            .setCurrentTimes(licenseData.getCurrentTimes() + 1);
                    setLicenseData(licenseData, licensePath);
                    return true;
                }
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return false;
        }
        return false;
    }

    public void genLicense(File licenseFile, String cryptedLicense)
            throws Exception
    {
        FileEncoder.encryptFile(licenseFile, cryptedLicense);
    }

    public boolean canUse(File license)
    {
        InputStream is;
        try
        {
            is = FileEncoder.decryptSource2Is(license);
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return false;
        }
        return this.judgeRes(is, license.getAbsolutePath());
    }
}